package com.fragments.sendmail;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ListView;
import android.widget.TextView;

import com.Utility.DownloadManager;
import com.Utility.MessageManager;
import com.Utility.Utility;
import com.Utility.WebServiceCommunicator.WebServiceFlag;
import com.adapters.FileAttachmentsAdapter;
import com.controls.ws.VaultWSControl;
import com.events.WebServiceCommunicatorListener;
import com.fragments.BaseFragment;
import com.objects.VaultFile;
import com.parser.Error_Report;
import com.senditcertified.mail.R;
import com.senditcertified.mail.widget.dialog.UploadDialog;
import com.soap.call.Http_Soap_Call;

public class AttachmentsFragment extends BaseFragment implements
		FileAttachmentsAdapter.OnClickAction, OnClickListener,
		WebServiceCommunicatorListener {
	private ListView mListFile;
	private FileAttachmentsAdapter mFileAdapter;
	private TextView mTvFileCount;
	private VaultWSControl mWSVault;
	private ArrayList<VaultFile> mFiles;
	private ProgressDialog mDialog;
	private VaultFile mFile;
	private UploadDialog mUploadDialog;
	private String mUploadFilePath;
	private UploadFileTask mUploadFileTask;

	public String getFiles() {
		StringBuilder files = new StringBuilder();
		for (int i = 0; i < mFileAdapter.getCount(); i++) {
			if(i > 0){
				files.append(',');
			}
			files.append(mFileAdapter.getItem(i).getName());
		}
		return files.toString();
	}

	@Override
	protected void initViews() {
		mListFile = (ListView) getView().findViewById(R.id.list_files);
		mTvFileCount = (TextView) getView().findViewById(
				R.id.tv_attach_file_count);

	}

	@Override
	protected void initComponents() {
		if (mFileAdapter == null) {
			mFileAdapter = new FileAttachmentsAdapter(getActivity(),
					new ArrayList<VaultFile>());
			mFileAdapter.setAction(this);

			mUploadDialog = new UploadDialog(getActivity().getParent(),
					new View.OnClickListener() {

						@Override
						public void onClick(View v) {
							Intent chooseFile;
							chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
							chooseFile.addCategory(Intent.CATEGORY_OPENABLE);

							chooseFile.setType("*/*");
							chooseFile = Intent.createChooser(chooseFile,
									"Choose a file");
							getActivity().getParent().startActivityForResult(
									chooseFile, 1000);
						}
					});
		}
		setFileCount(mFileAdapter.getCount());
		mListFile.setAdapter(mFileAdapter);

		mWSVault = new VaultWSControl(getActivity().getParent(), this);

		mDialog = new ProgressDialog(getActivity().getParent());
		mDialog.setCancelable(false);
		mDialog.setMessage(getString(R.string.loader));

	}

	public void setFileCount(int count) {
		mTvFileCount.setText(getString(R.string.send_mail_attach_files_count,
				count));
	}

	@Override
	protected void addListener() {
		getView().findViewById(R.id.btn_select_file).setOnClickListener(this);

	}

	@Override
	protected int initLayout() {
		// TODO Auto-generated method stub
		return R.layout.sendmail_attach_fragment;
	}

	@Override
	public void viewFile(VaultFile file, int position) {
		if (file.getViewUrl() == null) {
			mFile = file;
			mWSVault.getWebInterfaceVaultUrl(Utility.getStringPreference(
					getActivity().getParent(), Utility.KEY_LOGIN_TOKEN, "1"),
					file.getName());
		} else {
			if (file.getViewUrl() != null
					&& file.getViewUrl().startsWith("http")) {
				Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(file
						.getViewUrl()));
				startActivity(i);
			}
		}
	}

	@Override
	public void removeFile(VaultFile file, int position) {
		mFileAdapter.remove(file);
		mFileAdapter.notifyDataSetChanged();
		setFileCount(mFileAdapter.getCount());
	}

	@Override
	public void onClick(View v) {
		int id = v.getId();
		if (id == R.id.btn_select_file) {
			if (mFiles == null) {
				mWSVault.getVaultCatalog(Utility
						.getStringPreference(getActivity().getParent(),
								Utility.KEY_LOGIN_TOKEN, "1"));
			} else {
				selectFile();
			}
		} else {
		}
	}

	private void selectFile() {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()
				.getParent());
		String[] items = new String[mFiles.size() + 1];
		items[0] = "Add New File";
		for (int i = 0; i < mFiles.size(); i++) {
			items[i + 1] = mFiles.get(i).getName();
		}
		builder.setItems(items, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				switch (which) {
				case 0:
					mUploadDialog.show();
					break;

				default:
					VaultFile file = mFiles.get(which - 1);
					boolean isContain = false;
					for (int i = 0; i < mFileAdapter.getCount(); i++) {
						if (file.getName().equalsIgnoreCase(
								mFileAdapter.getItem(i).getName())) {
							isContain = true;
							break;
						}
					}
					if (!isContain) {
						mFileAdapter.add(file);
						mFileAdapter.notifyDataSetChanged();
						setFileCount(mFileAdapter.getCount());
					}
					break;
				}
			}
		});
		builder.create().show();
	}

	@Override
	public void onConnectionOpen(WebServiceFlag flag) {
		mDialog.show();
	}

	@Override
	public void onConnectionError(WebServiceFlag flag, String error) {
		if (mDialog.isShowing()) {
			mDialog.dismiss();
		}

	}

	@Override
	public void onConnectionDone(WebServiceFlag flag, String response) {
		if (mDialog.isShowing()) {
			mDialog.dismiss();
		}
		if (flag == WebServiceFlag.GET_VAULT_CATALOG) {
			mFiles = mWSVault.parseVaultFile(response);
			selectFile();

		} else if (flag == WebServiceFlag.GET_WEB_INTERFACE_VAULT_URL) {
			// TODO
			String link = mWSVault.parseAction(response,
					"GetWebInterfaceVaultURLResult");
			mFile.setViewUrl(link);
			if (link != null && link.startsWith("http")) {
				Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
				startActivity(i);
			}
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == 1000 && resultCode == Activity.RESULT_OK) {
			if (data != null && data.getData() != null) {
				String path = data.getData().getPath();
				if (!DownloadManager.isExist(path)) {
					path = getPath(data.getData());
				}
				if (!TextUtils.isEmpty(path)) {
					Log.e("Vault", path);
					File f = new File(path);
					mUploadFilePath = f.getAbsolutePath();
					if (mUploadFileTask != null) {
						mUploadFileTask.cancel(true);
						mUploadFileTask = null;
					}
					mUploadFileTask = new UploadFileTask();
					mUploadFileTask.execute(mUploadFilePath);
				} else {
					MessageManager.showToast(getActivity().getParent(),
							"Can't get this file");
				}
			} else {
				MessageManager.showToast(getActivity().getParent(),
						"Can't get this file");
			}
		}
	}

	public String getPath(Uri uri) {
		String[] projection = { MediaStore.Images.Media.DATA };
		Cursor cursor = getActivity().managedQuery(uri, projection, null, null,
				null);
		if (cursor != null) {
			// HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
			// THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			return cursor.getString(column_index);
		} else
			return null;
	}

	private class UploadFileTask extends AsyncTask<String, Void, String> {
		private File uploadFile;
		private Error_Report repor = new Error_Report();
		private ProgressDialog dialog;

		@Override
		protected void onCancelled() {
			if (dialog.isShowing()) {
				dialog.dismiss();
			}
			super.onCancelled();
		}

		@Override
		protected void onPreExecute() {
			dialog = new ProgressDialog(getActivity().getParent());
			dialog.setMessage(getString(R.string.uploading));
			dialog.setCancelable(false);
			dialog.show();
		}

		@Override
		protected String doInBackground(String... params) {
			uploadFile = new File(params[0]);
			try {
				if (uploadFile.exists()) {

					byte b[][] = toByteArray(uploadFile, 262144);

					Http_Soap_Call call = Http_Soap_Call.create_connection("",
							getActivity().getParent());
					if (call != null && b != null) {
						for (int i = 0; i < b.length; i++) {
							call.GetUploadFileResponse(Utility
									.getStringPreference(getActivity()
											.getParent(), "LoginToken", "1"),
									params[0], b[i], i * 262144, repor);
						}

					} else {
						return "No Connection!";
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
				return e.getMessage();
			} catch (OutOfMemoryError e) {
				e.printStackTrace();
				return e.getMessage();
			}

			return "OK";
		}

		@Override
		protected void onPostExecute(String result) {
			if (dialog != null) {
				dialog.dismiss();
				dialog = null;
			}

			if ("OK".equals(result)) {
				if (mUploadDialog.isShowing()) {
					mUploadDialog.dismiss();
				}
				VaultFile file = new VaultFile();
				file.setName(new File(mUploadFilePath).getName());
				mFileAdapter.add(file);
				mFileAdapter.notifyDataSetChanged();
				setFileCount(mFileAdapter.getCount());

				mFiles = null;
			} else {
				MessageManager.showToast(getActivity().getParent(), result);
			}
		}

	}

	public byte[][] toByteArray(File file, int byteBlockSize)
			throws IOException {
		if (file.exists()) {
			InputStream in = new FileInputStream(file);
			long noOfBlocks = (long) Math.ceil((double) file.length()
					/ (double) byteBlockSize);
			byte[][] result = new byte[(int) noOfBlocks][byteBlockSize];
			int offset = 0;
			for (int i = 0; i < result.length; i++) {
				result[i] = readByteBlock(in, offset, byteBlockSize);
			}
			return result;
		} else
			return null;
	}

	private byte[] readByteBlock(InputStream in, int offset, int noBytes)
			throws IOException {
		byte[] result = new byte[noBytes];
		in.read(result, offset, noBytes);
		return result;
	}

}
